package client

import (
	"context"
	"fmt"
	"meta-self/internal/consts"
	"meta-self/internal/dao"
	"meta-self/internal/model/entity"
	"meta-self/internal/model/input/clientin"
	"meta-self/internal/model/input/payin"
	"meta-self/internal/pkg/contexts"
	"meta-self/internal/pkg/payment"
	"meta-self/internal/service"

	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
)

type sSysOrder struct{}

func init() {
	service.RegisterSysOrder(&sSysOrder{})
}

// Model 充值订单ORM模型
func (s *sSysOrder) Model(ctx context.Context) *gdb.Model {
	return dao.SysOrder.Ctx(ctx)
}

// ApplyRefund 申请退款
func (s *sSysOrder) ApplyRefund(ctx context.Context, in *clientin.OrderApplyRefundInp) (err error) {
	view, err := s.View(ctx, &clientin.OrderViewInp{Id: in.Id})
	if err != nil {
		return err
	}

	if view == nil {
		err = gerror.New("订单不存在")
		return
	}

	if view.Status == consts.OrderStatusReturnRequest {
		err = gerror.New("当前订单退款正在申请处理，请勿重复提交！")
		return
	}

	if view.Status != consts.OrderStatusDone {
		err = gerror.New("当前订单状态不支持申请退款，如有疑问请联系管理员！")
		return
	}

	update := g.Map{
		dao.SysOrder.Columns().Status:       consts.OrderStatusReturnRequest,
		dao.SysOrder.Columns().RefundReason: in.RefundReason,
	}

	_, err = s.Model(ctx).Where(dao.SysOrder.Columns().Id, in.Id).Data(update).Update()
	return
}

// PayNotify 支付成功通知
func (s *sSysOrder) PayNotify(ctx context.Context, in *payin.NotifyCallFuncInp) (err error) {
	var models *entity.SysOrder
	if err = s.Model(ctx).Where(dao.SysOrder.Columns().OrderSn, in.Pay.OrderSn).Scan(&models); err != nil {
		return
	}

	if models == nil {
		err = gerror.New("订单不存在")
		return
	}

	if models.Status != consts.OrderStatusNotPay {
		err = gerror.New("订单已被处理，无需重复操作")
		return
	}

	err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
		// 更新订单状态
		_, err = s.Model(ctx).Where(dao.SysOrder.Columns().Id, models.Id).Data(g.Map{
			dao.SysOrder.Columns().Status: consts.OrderStatusDone,
		}).Update()
		if err != nil {
			return
		}

		// 根据订单类型处理不同的业务逻辑
		if models.OrderType == consts.OrderTypeProduct {
			// 如果是购买产品订单，则需要激活关联的卡密
			// 根据产品ID获取关联的卡密
			var licenseKey *entity.SysLicenseKeys
			err = dao.SysLicenseKeys.Ctx(ctx).
				Where(dao.SysLicenseKeys.Columns().Status, consts.LicenseKeyStatusPending).
				Where(dao.SysLicenseKeys.Columns().Id, models.ProductId). // 假设ProductId关联到卡密ID
				Scan(&licenseKey)

			if err != nil {
				return err
			}

			if licenseKey == nil {
				g.Log().Errorf(ctx, "订单[%s]支付成功，但未找到关联的待激活卡密，ProductId: %d", models.OrderSn, models.ProductId)
				return nil
			}

			// 调用卡密激活服务
			_, err = service.LicenseKey().Activate(ctx, &clientin.LicenseKeyActivateInp{
				KeyString: licenseKey.KeyString,
				UserId:    models.UserId,
			})

			if err != nil {
				g.Log().Errorf(ctx, "订单[%s]支付成功，但激活卡密失败: %v", models.OrderSn, err)
				return err
			}

			g.Log().Infof(ctx, "订单[%s]支付成功，已自动激活卡密: %s", models.OrderSn, licenseKey.KeyString)
		}

		return
	})

	if err != nil {
		return
	}

	return
}

// Create 创建充值订单
func (s *sSysOrder) Create(ctx context.Context, in *clientin.OrderCreateInp) (res *clientin.OrderCreateModel, err error) {
	var (
		subject = "支付订单"
		orderSn = payment.GenOrderSn()
	)

	switch in.OrderType {
	case consts.OrderTypeBalance:
		subject = fmt.Sprintf("余额充值:￥%v", in.Money)
	case consts.OrderTypeProduct:
	default:
		err = gerror.New("不支持的订单类型")
		return
	}

	res = new(clientin.OrderCreateModel)
	err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
		orderId, err := s.Model(ctx).Data(entity.SysOrder{
			UserId:    contexts.GetUserId(ctx),
			OrderType: in.OrderType,
			ProductId: uint64(in.ProductId),
			OrderSn:   orderSn,
			Money:     in.Money,
			Remark:    in.Remark,
			Status:    consts.OrderStatusNotPay,
		}).OmitEmptyData().InsertAndGetId()
		if err != nil {
			return
		}

		create, err := service.Pay().Create(ctx, payin.PayCreateInp{
			Subject:    subject,
			OrderSn:    orderSn,
			OrderGroup: consts.OrderGroupDefault,
			PayType:    in.PayType,
			TradeType:  in.TradeType,
			PayAmount:  in.Money,
			ReturnUrl:  in.ReturnUrl,
		})
		if err != nil {
			return err
		}

		res.Order = create.Order
		res.Order.Id = orderId
		return
	})
	return
}

// View 获取充值订单指定信息
func (s *sSysOrder) View(ctx context.Context, in *clientin.OrderViewInp) (res *clientin.OrderViewModel, err error) {
	err = s.Model(ctx).Where(dao.SysOrder.Columns().Id, in.Id).Scan(&res)
	return
}
